package com.bombitarodriguez.dominio.personaje;


import java.util.ArrayList;
import java.util.Iterator;
import com.bombitarodriguez.dominio.Casillero;
import com.bombitarodriguez.dominio.Juego;
import com.bombitarodriguez.dominio.Mapa;
import com.bombitarodriguez.dominio.Posicion;
import com.bombitarodriguez.dominio.armas.Bomba;
import com.bombitarodriguez.dominio.armas.FactoryArma;
import com.bombitarodriguez.dominio.armas.Proyectil;
import com.bombitarodriguez.dominio.obstaculosYArticulos.Obstaculo;
import com.bombitarodriguez.interfaces.Armado;
import com.bombitarodriguez.interfaces.ObjetoReaccionable;

import fiuba.algo3.titiritero.dibujables.Imagen;
import fiuba.algo3.titiritero.modelo.ObjetoPosicionable;


/**
 * 
 * 
 *
 */
public abstract class Personaje 
implements ObjetoReaccionable, Armado, ObjetoPosicionable{
	
	protected Imagen miVista;
	
	public Imagen getVista(){
		return miVista;
	}
	
	@Override
	public int getX() {
		Integer enteroAux = 
				casilleroContenedor.getPosicion().getPosX() - 1;
		enteroAux = enteroAux * Juego.TAMANIO_IMAGEN ;;
		return (enteroAux);
	}

	@Override
	public int getY() {
		Integer enteroAux = casilleroContenedor.getPosicion().getPosY();
		enteroAux = Juego.ANCHO_MAPA - enteroAux;
		enteroAux = (enteroAux * Juego.TAMANIO_IMAGEN );
		return (enteroAux);
	}


	protected Casillero casilleroContenedor;
	
	
	@Override
	public Boolean reaccionarCon(Bomba bomba) {
		//los personajes no pueden pasar si hay una bomba
		return false;
	}


	protected Integer velocidad;
	
	protected FactoryArma factoryArma;
		
	private void intentarMoverse(Casillero casilleroDondeQuieroIr){
		/*
		 * copio la lista de objetos del casillero
		 * si todos los objetos me dejan pasar
		 * lo hago
		 */
		ArrayList<ObjetoReaccionable> copiaDeLaListaDeObjetos = 
				new ArrayList<ObjetoReaccionable>();
		Iterator <ObjetoReaccionable> iteradorDeObjetos = 
				casilleroDondeQuieroIr.getObjetos().iterator();
		while (iteradorDeObjetos.hasNext()){
			copiaDeLaListaDeObjetos.add(iteradorDeObjetos.next());
		}
		iteradorDeObjetos = 
				copiaDeLaListaDeObjetos.iterator();
		if (reaccionarConTodos(iteradorDeObjetos)) {
			Mapa.getMapa().reposicionar(this, casilleroDondeQuieroIr);
		}
		
	}
	
	public void moverArriba() {
		Posicion siguientePosicion = 
				Posicion.calcularPosicionArriba(this, 1);
		if (Posicion.posicionValida(siguientePosicion)){
			Casillero casilleroProximo = 
					Mapa.getMapa().getCasillero(siguientePosicion);
			intentarMoverse(casilleroProximo);
		}
	}
	
	public void moverDerecha() {
		Posicion siguientePosicion = 
				Posicion.calcularPosicionDerecha(this, 1);
		if (Posicion.posicionValida(siguientePosicion)){
			Casillero casilleroProximo = 
					Mapa.getMapa().getCasillero(siguientePosicion);
			intentarMoverse(casilleroProximo);
		}
	}
	
	public void moverAbajo() {
		Posicion siguientePosicion = 
				Posicion.calcularPosicionAbajo(this, 1);
		if (Posicion.posicionValida(siguientePosicion)){
			Casillero casilleroProximo = 
					Mapa.getMapa().getCasillero(siguientePosicion);
			intentarMoverse(casilleroProximo);
		}
	}
	
	public void moverIzquierda() {
		Posicion siguientePosicion = 
				Posicion.calcularPosicionIzquierda(this, 1);
		if (Posicion.posicionValida(siguientePosicion)){
			Casillero casilleroProximo = 
					Mapa.getMapa().getCasillero(siguientePosicion);
			intentarMoverse(casilleroProximo);
		}	
	}

	/**
	 * Permite reaccionar con todos los objetos de un casillero
	 * @param iterador
	 * @return true si se puede mover, false caso contrario
	 */		
	
	
	public Integer getVelocidad() {
		return this.velocidad;
	}

	
	public Casillero getCasillero() {
		return casilleroContenedor;
	}
	
	@Override
	public Posicion getPosicion() {
		return casilleroContenedor.getPosicion();
	}

	@Override
	public void setCasillero(Casillero casillero) {
		casilleroContenedor = casillero;		
	}

	public FactoryArma getFactoryArma() {
		return factoryArma;
	}

	
	@Override
	public void usarArma() {
		getCasillero().agregarObjeto(factoryArma.getArmaInstanciada());		
	}

	
	@Override
	public Boolean reaccionarCon(Proyectil proyectil){
		proyectil.explotar();
		return false;
	}
	@Override
	public Boolean reaccionarCon(Obstaculo obstaculo){
		return false;
	}
	
	
	abstract Boolean reaccionarConTodos(Iterator<ObjetoReaccionable> iterador);

		
	
}
